package com.zenchn.utils;

import org.apache.commons.codec.digest.DigestUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Random;
import java.util.UUID;

/**
 * CommonUtils : 通用工具类，提供大量的便捷方法
 *
 * @author dingxinfa
 * @date 2018-08-18
 */
public class CommonUtils {

    /**
     * 产生一个32个字符的UUID
     *
     * @return UUID
     */
    public static String randomUUID() {
        return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }

    /**
     * md5加密
     *
     * @param value 要加密的值
     * @return md5加密后的值
     */
    public static String md5Hex(String value) {
        return DigestUtils.md5Hex(value);
    }

    /**
     * sha1加密
     *
     * @param value 要加密的值
     * @return sha1加密后的值
     */
    public static String sha1Hex(String value) {
        return DigestUtils.sha1Hex(value);
    }

    /**
     * sha256加密
     *
     * @param value 要加密的值
     * @return sha256加密后的值
     */
    public static String sha256Hex(String value) {
        return DigestUtils.sha256Hex(value);
    }


    /***
     * 获取文件MD5 值
     * @param file
     * @return
     */
    public static String md5HexByFile(File file) {
        String value = null;
        try {
            value = DigestUtils.md5Hex( new FileInputStream(file)).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }

    /***
     * 获取文件MD5 值
     * @param filePath
     * @return
     */
    public static String md5HexByFile(String filePath) {
        String value = null;
        try {
            value = DigestUtils.md5Hex( new FileInputStream(filePath)).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }


    /***
     * 获取 输入流 MD5 值
     * @param inputStream
     * @return
     */
    public static String md5HexByInputStream(InputStream inputStream) {
        String value = null;
        try {
            value = DigestUtils.md5Hex(inputStream).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }


    /***
     * 获取 字节流 MD5 值
     * @param bytes
     * @return
     */
    public static String md5HexByBytes(byte[] bytes) {
        String value = null;
        try {
            value = DigestUtils.md5Hex(bytes).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }




    /**
     *
     * 比较版本号的大小,返回大的版本号
     *
         注意：其中 split 方法入参为正则匹配表达式，不能用"."("."在正则表达式里匹配任何值)，需要用"\\."，才算是按点号分割；
         这样，先分割成子串数组，再挨个比较子版本号，比较子版本号时，先比较位数，位数大的就大，位数一样时再按字符串比较方式比较；
         如果全部比较完（其中一个版本号比较完）之后，再看一下哪个版本号有更更多的子版本号，也就是分割后的数组长度，有子版本号的为大；
         这样就比较完善地考虑了各种情况，并比较出版本号大小；包括有字母后缀的也可以使用；
         如 "9.9", "10.8.8.6" ，如果直接按字符串比较，则会前者大，后者小，而明显是错误的；分割后比较第一个主版本9与10，从位数上，就已经得出结果后者大；
         再如 "9.9b", "9.8a" 等也适用，如果用转换成int或者double的方法就不适用；
     * @param version1
     * @param version2
     * @return
     */
    public static String compareVersion(String version1, String version2){
        //注意此处为正则匹配，不能用"."；
        String[] versionArray1 = version1.split("\\.");
        String[] versionArray2 = version2.split("\\.");
        int idx = 0;
        //取最小长度值
        int minLength = Math.min(versionArray1.length, versionArray2.length);
        int diff = 0;
        //先比较长度
        //再比较字符
        while (idx < minLength
                && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0
                && (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {
            ++idx;
        }
        //如果未分出大小，则再比较位数，有子版本的为大；
        if (diff==0){
            diff = versionArray1.length - versionArray2.length;
        }
        //version1 >  version2  diff>0
        //version1 ==  version2  diff==0
        //version1 < version2  diff<0
        return diff>0? version1:version2;
    }

    /**
     * 随机字母数字
     * @return
     */
    public static String randomAlphanumeric(int length) {
        String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random1=new Random();
        //指定字符串长度，拼接字符并toString
        StringBuffer sb=new StringBuffer();
        for (int i = 0; i < length; i++) {
            //获取指定长度的字符串中任意一个字符的索引值
            int number=random1.nextInt(str.length());
            //根据索引值获取对应的字符
            char charAt = str.charAt(number);
            sb.append(charAt);
        }
        return  sb.toString();
    }

    /**
     * 随机数字
     * @return
     */
    public static String randomNumber(int length) {
        StringBuffer sb=new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(random.nextInt(10));
        }
        return  sb.toString();
    }

}
